/**
 *  1、内联函数
 *  2、静态成员
 *  3、const
 *  4、无法实例化对象的类
 *  5、无法被继承的类final
 *  6、delete的特殊用法
 *  7、友元
 *  8、名字空间
 */
#include <iostream>


// 宏函数
# define ADD(a,b)  (a+b)

// 内联函数
inline int add(int& a, int &b)
{
    return a+b;
}

// 模板内联函数，返回两个数中较大的值
template <typename T>
inline T max(T a, T b) {
    return a > b? a : b;
}

class optData{
public:
    // 类中内联函数
    inline int add(int& a, int &b){
        return a+b;
    }
};

class Student {
public:
    Student(std::string name) :
        m_name(name)
    {
        ++m_totalStudents;
    }

    Student(std::string name, std::string strlocal) : m_name(name),
        m_strLocal(strlocal)
    {
        ++m_totalStudents;
    }

    ~Student() {
        --m_totalStudents;
    }
    // 静态成员函数
    static int getTotalStudents() {
        // ++m_totalStudents; 错误静态成员函数中不能出现普通成员变量，这里仅能操作静态成员变量；
        return m_totalStudents;
    }

    static std::string getSchoolName(){
        return m_schoolName;
    }

    // 普通成员函数
    int getStudentsCount()
    {
        return getTotalStudents();
    }
    
    std::string getSchoolLocation(){
        return m_strLocal;
    }

    void setSex(const std::string strSex){
        // 传入的形参不能修改；
        m_strSex = strSex;
    }

    const std::string getSex(){
        return m_strSex;
    }

    // 不能修改所有成员变量
    void getStudetCount(int &count) const{
        count = m_totalStudents;
    }

private:
    const std::string m_strLocal{"上海"};
    std::string m_name;
    std::string m_strSex;
    // 静态成员变量
    static std::string m_schoolName;
    static int m_totalStudents;
};

std::string Student::m_schoolName = "上海中学";
int Student::m_totalStudents = 0;

// 构造函数私有
class baseClass {
private:
    baseClass(){
        std::cout << "构造函数" <<std::endl;
    }

private:
    int m_num;
};

// 无法继承的类
class NonInheritable final {
public:
    void print() {
        std::cout << "This is a final class." << std::endl;
    }
};


class MyClass {
public:
    MyClass(int value) : m_data(value) {}
    // 删除默认构造函数
    MyClass() = delete; 
private:
    int m_data;
};

class NonCopyable {
public:
    NonCopyable() = default;
    // 删除拷贝构造函数
    NonCopyable(const NonCopyable&) = delete; 
    // 删除拷贝赋值运算符
    NonCopyable& operator=(const NonCopyable&) = delete; 
};

class A {
public:
    A(int data) : m_privateData(data) {}

protected:
    double m_protectedData{3.88};

private:
    friend void friendFunction(A& a); // 友元函数
    friend class ClassB; // 友元类

private:
    int m_privateData;
};

void friendFunction(A& a) {
    std::cout << "访问到私有数据：" << a.m_privateData << std::endl;
}

class ClassB {
public:
    void accessClassAData(A& obj) {
        // 友元类可以访问 ClassA 的私有和受保护成员
        std::cout << "Accessing private data of Class A: " << obj.m_privateData << std::endl;
        std::cout << "Accessing protected data of Class A: " << obj.m_protectedData << std::endl;
    }
};

// 名字空间
namespace Math {
    int add(int a, int b) {
        return a + b;
    }
}

namespace Utility {
    int add(int a, int b) {
        return a * b;
    }
}

int main()
{
    // 内联函数
    {
        int n = 5;
        int m = 13;
        std::cout << "sum1: " << add(n,m) << std::endl;
        std::cout << "sum2: " << ADD(n,m) << std::endl;
    
        optData opt;
        std::cout << "sum3: " << opt.add(n,m) << std::endl;
    
        int iMax = max(n, m);
        std::cout << "iMax: " << iMax << std::endl;
    }

    // 静态成员
    {
        Student stu1("小明");
        Student stu2("小红");
        std::cout << "学生总数：" << Student::getTotalStudents() << " 学校名："<< Student::getSchoolName()<<std::endl;
        std::cout << "小明知道的学生总数：" << stu1.getStudentsCount() << std::endl;
    }

    // const
    {
        Student stu1("小王");
        stu1.setSex("男");
        Student stu2("小丽");
        stu2.setSex("女");
        Student stu3("小张", "北京");
        stu3.setSex("男");
        int stuCount = 0;
        stu2.getStudetCount(stuCount);
        std::cout << "小王学校在哪儿：" << stu1.getSchoolLocation() << " 小王性别：" << stu1.getSex() << std::endl;
        std::cout << "小丽学校在哪儿：" << stu2.getSchoolLocation() << " 小丽学校学生数量:" << stuCount <<std::endl;
        std::cout << "小张学校在哪儿：" << stu3.getSchoolLocation() << std::endl;
        
    }

    {
        NonInheritable table;
        table.print();
    }

    {
        // MyClass obj; // 错误，默认构造函数已被删除
        MyClass obj(42); // 正确，使用带参数的构造函数

        NonCopyable obj1;
        // NonCopyable obj2 = obj1; // 错误，拷贝构造函数已被删除
        // NonCopyable obj3;
        // obj3 = obj1; // 错误，拷贝赋值运算符已被删除
    }

    // 友元
    {
        A a(10);
        friendFunction(a);
        ClassB b;
        b.accessClassAData(a);
    }
   
    // 名字空间
    {
        std::cout << "Math 名字空间的加法：" << Math::add(3, 5) << std::endl;
        std::cout << "Utility 名字空间的加法：" << Utility::add(3, 5) << std::endl;
    }

    return 0;
}